home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 Extra Demos / User Contributions / ButtonBreakOut ƒ / DataPersistence / DataPersistence.note < prev   
Encoding:
Text File  |  1999-01-11  |  8.8 KB  |  207 lines  |  [TEXT/CWIE]

  1. /*———————————————————————————————————————————————————————————————————————————————————————————————————
  2.                                     DATA PERSISTENCE README
  3.                                     ———————————————————————
  4.     • WHAZZAT
  5.  
  6.     Very general mini-module for saving and restoring arbitrary blocks of data, in 
  7.     resource format in a separate file. It's very small (1K including data), very 
  8.     simple (four main routines), and does the job, at least for me.
  9.  
  10.     This code was initially part of SpritePersistence. On second thought,it's better 
  11.     and more useful as a separate module, so it was made into one.
  12.  
  13.  
  14.     • USAGE
  15.  
  16.     This is it:
  17.  
  18.         err = SWGOpenPersistenceFile ();                            // note: no args
  19.                                                                     // should ALWAYS check error!..
  20.         err = SWGSaveRecord (yourDataPtr, yourDataSize, resID);        // or SWGLoadRecord
  21.                                                                     // should ALWAYS check error!..
  22.         SWGClosePersistenceFile ();
  23.  
  24.     That's all folks. It looks simple enough to me not to need a lot of comment...
  25.  
  26.  
  27.     • FUNCTION REFERENCE
  28.  
  29.     1. File
  30.  
  31.         OSErr    SWGOpenPersistenceFile (void);
  32.  
  33.                 No arguments: the file name is a customizable global pascal string
  34.                 named gPersistenceFileName (see DataPersistence.h; change it if you like).
  35.                 System errors may be returned. But fnfErr (file not found) will never
  36.                 be returned: if file is absent, we will switch to application resource mode
  37.                 (see the File Management section).
  38.  
  39.         void    SWGClosePersistenceFile (void);
  40.  
  41.                 Guess.
  42.  
  43.         Boolean    SWGOpenPersistenceFileConditionally (OSType newType);
  44.  
  45.                 newType: optionally overrides DataPersistence's standard resource 
  46.                         type. If you pass kNoNewType, there will be no override. 
  47.                         You normally don't need this, it's mainly for SpritePersistence which 
  48.                         uses the override mechanism to avoid overwriting your own resources.
  49.  
  50.                 This is primarily for the benefit or SpritePersistence. (Have a look at 
  51.                 SpritePersistence if you want to see the reason.)
  52.  
  53.                 - It returns true if the file was previously closed, and it has just opened the 
  54.                 file; after that, your routine is responsible for closing the file, using
  55.                 SWGClosePersistenceFile() before returning. 
  56.  
  57.                 - If it returns false, the file was already open, and it must stay open when
  58.                 your routine terminates. So your routine must _not_ close the file.
  59.  
  60.                 For an example of usage, see the SpritePersistence module, 
  61.                 SWGSaveSpritesInAllLayers and SWGSaveSpritesInLayer.
  62.  
  63.                 There are twe reasons you may want to use this instead of SWGOpenPersistenceFile.
  64.                 One is if you really need to override the default resource type ('PERS'). 
  65.                 The second is the same reason SpritePersistence uses it: when there are 
  66.                 several nested routines, it allows calling directly one of the lower-level
  67.                 nested ones. It resolves the problem "should I open the file/should I close it?".
  68.                 (Again, look at SpritePersistence if you want a detailed look at this issue.)
  69.  
  70.     2. Read/Write
  71.  
  72.         OSErr    SWGSaveRecord (Ptr recordP, Size recSize, SInt16 resourceID);
  73.         OSErr    SWGLoadRecord (Ptr recordP, Size recSize, SInt16 resourceID);
  74.  
  75.             For both:
  76.  
  77.                 recordP:     pointer to your data (if dereferenced handle, *lock* it)
  78.                 recSize:     *exact* number of bytes to read/write
  79.                 resourceID: whatever you like (apple-recommended range 128..32767,
  80.                             but actually we may use -32768..32767 as there should be
  81.                             no conflict between gSWGPersistenceResourceType (which is
  82.                             'PERS' by default) and apple resources.
  83.  
  84.         OSErr    SWGSaveString (Ptr stringP, Size stringSize, SInt16 resourceID);
  85.  
  86.                 This is strictly indentical to SWGSaveRecord; it's here for symmetry 
  87.                 with SWGLoadString.
  88.  
  89.                 The following is nearly identical with SWGLoadRecord, but with a little twist
  90.                 which regards error reporting:
  91.  
  92.         OSErr    SWGLoadString (Ptr stringP, Size maxStringSize, SInt16 resourceID);
  93.  
  94.                 stringP:         pointer to your data (if dereferenced handle, *lock* it)
  95.                 maxStringSize:     *max* number of bytes to read/write
  96.                 resourceID:     same as above
  97.  
  98.                 The only difference between SWGLoadRecord and SWGLoadString is tolerance to
  99.                 an unexpected file data size:
  100.  
  101.                 - SWGLoadRecord expects an exact size and will report an error if another size
  102.                 is found (you are free to ignore the error if you feel it's appropriate). It
  103.                 may report system errors, plus the two specials: kDataSizeBiggerError and 
  104.                 kDataSizeSmallerError.
  105.  
  106.                 - SWGLoadString considers data smaller than expected as normal, and only 
  107.                 reports an error if the data is *bigger* than expected. It may report system 
  108.                 errors, plus one special: kDataSizeBiggerError.
  109.  
  110.     3. Errors
  111.  
  112.         void    SWGErrorReportingStub (OSErr err);
  113.  
  114.                 If there's an error, will beep. Change this behavior to whatever
  115.                 sophisticated behavior each app needs. 
  116.                 If there's no error, does nothing; which allows you to call it
  117.                 systematically, if you prefer having a slightly more compact source 
  118.                 code at the expense of a few clock cycles at runtime.
  119.  
  120.  
  121.     • NOTES
  122.  
  123.     1.     ** IMPORTANT AND USEFUL ** : you may change data block sizes at any time. 
  124.     DataPersistence automatically resizes the resource when asked to write a data block 
  125.     with a modified size.
  126.  
  127.     2. Error checking is recommended (yes, I know you know :)
  128.     If you don't really want to go to a lot of trouble, there's a simple error routine 
  129.     in DataPersistence, called SWGErrorReportingStub. You could do this:
  130.  
  131.         err = SWGOpenPersistenceFile ();
  132.         SWGErrorReportingStub (err);                            // beeps only if err
  133.         err = SWGSaveRecord (yourDataPtr, yourDataSize, resID);
  134.         SWGErrorReportingStub (err);                            // beeps only if err
  135.         SWGClosePersistenceFile ();
  136.  
  137.     3. When writing, DataPersistence automatically creates a resource when it didn't 
  138.     already exist.
  139.  
  140.     4. When reading, if a resource doesn't exist, DataPersistence zeroes the recordP and 
  141.     returns with resNotFound. This will usually happen only after the first launch.
  142.  
  143.     5. ** Warning ** : if yourDataPtr is a dereferenced handle, *lock* the handle before 
  144.     calling; you can of course unlock it just after the call. Never ever call with an 
  145.     unlocked dereferenced handle, it always brings bad luck (and sometimes bad crashes :)
  146.  
  147.     6. If you need to manually edit some of your saved data: look in the saved file (or 
  148.     the app's resource fork if that's what you use), for the resource type 'PERS'. This 
  149.     default type is defined by kDefaultPersistenceRezType in file DataPersistence.h 
  150.     (change it if you wish). If you want to edit sprite data: SpritePersistence overrides 
  151.     the standard resource type and uses type 'SPRI', defined by kSpriteSaveRezType in 
  152.     SpritePersistence.h (change it if you wish).
  153.  
  154.  
  155.     • FILE MANAGEMENT
  156.  
  157.     DataPersistence normally uses a separate resource file, named "Data Persistence" by 
  158.     default, which resides in the app's folder. This is the recommended usage: the app's 
  159.     own resources will be clobbered the very next time you rebuild it.
  160.  
  161.     The default data file name may be changed: gPersistenceFileName in DataPersistence.h .
  162.  
  163.     There's an alternative mode which uses the app's resource fork.
  164.  
  165.     If the "Data Persistence" file is not found, we automatically switch to the other mode,
  166.     which uses the application resource fork. To go back to the recommended separate-file 
  167.     mode, simply quit your app, bring back the "Data Persistence" file in the app's folder, 
  168.     and relaunch.
  169.  
  170.     Note: you are free to give any file type and creator to the "Data Persistence" file. 
  171.     DataPersistence identifies the file from it's name and it's location in the app's 
  172.     folder, not from the type and creator.
  173.  
  174.     Note 1: the alternative mode using app resources has a side-effect: the data file is
  175.     _not_ created implicitly, when it is not found. If you want it you must create it
  176.     yourself.
  177.  
  178.     Note 2: this is a *resource* file. This means you must have created it with resedit 
  179.     or resorcerer (for example), definitely not with your favorite text editor.
  180.  
  181.     Note on resource format
  182.     -----------------------
  183.     The data is saved in resource format; you may inspect it or edit it manually with 
  184.     resedit/resorcerer. This format is not intended for a large number of stored elements 
  185.     (e.g. in the thousands). But resources are very convenient, and there are many 
  186.     toolbox calls and many utility programs for manipulating them. Even if we need 
  187.     several thousand elements, it will work perfectly, although a little more slowly. 
  188.     In most cases, this won't be a drawback, since most read/writes will be 
  189.     done when the animation isn't running. 
  190.  
  191.     If necessary in the future, it would be reasonably easy to modify SWGSaveRecord and 
  192.     SWGLoadRecord, using a custom data format. It looks like unneeded work at then moment,
  193.     and it would make this module significantly larger (think of the automatic record 
  194.     resizing facility). If you become unhappy with using resources, why not say so... we'll 
  195.     talk about it.
  196.  
  197.  
  198.     • FAQ
  199.  
  200.     ----- 1 -----
  201.  
  202.     Q: I have no questions at this time, bud.
  203.     A: Why?
  204.  
  205. ———————————————————————————————————————————————————————————————————————————————————————————————————*/
  206. // feedback: macdev@tnuctip.com
  207.